/**
 *	Win conditions specific to noughts and crosses (large)
**/

"use strict"


GameLogic.winChecker.addRules({
	
	// invoke a meta-rule to deal with rows of arbitrary numbers
	checkRowOf3: function(game) {
		return this.metaCheckRowOfX(game, 3)
	},
	
	checkColumnOf3: function(game) {
		return this.metaCheckColumnOfX(game, 3)
	},
	
	checkDiagonalOf3: function(game) {
		return this.metaCheckDiagonalOfX(game, 0, 0, 3)
	},
	
	
	// metarule - deals with long rows and a subset of those being necessary to win!
	metaCheckRowOfX: function(game, winLength) {
		var state = game.state, rowCount, currentSquare
		
		for (var y=0, yy=state.length; y<yy; y++) {
			rowCount = 0, currentSquare = null
			
			for (var x=0, xx=state[0].length; x<xx; x++) {
				// if currentSquare is not the same as the last square we checked, reset the count...
				if (currentSquare !== state[y][x]) {
					rowCount = 1
					currentSquare = state[y][x]
				
				// ...otherwise increment the count
				} else {
					rowCount++
				}
				
				// if the current square is not empty (0) and we've counted up to winLength, return the winner
				if (currentSquare !== 0 && rowCount === winLength) {
					return currentSquare
				}
				
			} // end for x
			
		} // end for y
		
		// must be no matching rows, so return 0 (game still in progress)
		return 0
	},
	
	
	// metarule - deals with long rows and a subset of those being necessary to win!
	metaCheckColumnOfX: function(game, winLength) {
		var state = game.state, rowCount, currentSquare
		
		for (var x=0, xx=state.length; x<xx; x++) {
			rowCount = 0, currentSquare = null
			
			for (var y=0, yy=state[0].length; y<yy; y++) {
				// if currentSquare is not the same as the last square we checked, reset the count...
				if (currentSquare !== state[y][x]) {
					rowCount = 1
					currentSquare = state[y][x]
				
				// ...otherwise increment the count
				} else {
					rowCount++
				}
				
				// if the current square is not empty (0) and we've counted up to winLength, return the winner
				if (currentSquare !== 0 && rowCount === winLength) {
					return currentSquare
				}
				
			} // end for y
			
		} // end for x
		
		// must be no matching rows, so return 0 (game still in progress)
		return 0
	},
	
	
	// metarule - deals with arbitrary sized diagonals using recursion!
	metaCheckDiagonalOfX: function(game, xpos, ypos, crosssize) {
		var fname = "metaCheckDiagonalOfX"		//name of the function in 'this' scope
		
		if ( ypos + crosssize > game.board.h) {
			return 0										// column to close to bottom - must be no winner yet
		} else if ( xpos + crosssize > game.board.w ) {
			return this[fname](game, 0, ypos+1, crosssize)		// row too close to horizontal edge - go to next row
		}
		
		// locate the first item to check against
		var selectedItemFS = game.state[ypos][xpos],				//forward slash
			selectedItemBS = game.state[ypos][xpos+crosssize-1],	//back slash
			failFS = false,		// failure state
			failBS = false
		
		// loop through based on the cross size
		for (var i=0; i<crosssize; i++) {
			if ( selectedItemFS === 0 || game.state[ypos+i][xpos+i] !== selectedItemFS ) {
				failFS = true
			}
			if ( selectedItemBS === 0 || game.state[ypos+i][(xpos+crosssize-1)-i] !== selectedItemBS ) {
				failBS = true
			}
			
			//console.log(failFS + ":" + failBS)
			if ( failFS && failBS ) {
				return this[fname](game, xpos+1, ypos, crosssize)	// increment xpos and recurse!
			}
		}
		
		// must have found something at this point
		return ( failFS === false ? selectedItemFS : selectedItemBS )
	}
	
})